#!/usr/bin/python
#coding=utf-8

from __future__ import division
import re
import sys
import urllib
import urllib2
import datetime
import json
import time
import random
import decimal
import threading
from common import *

reload(sys)  
sys.setdefaultencoding('utf-8')

'''
视频解析类
@author garethxiao@qq.com
'''
class FCFLV(object):
    def __init__(self):
        self.url = ""
        self.headers = {"Accept":"*/*", "Accept-Language":"zh-CN", "":"", 
                        "User-Agent":"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1482.0 Safari/537.36", 
                        #"Accept-Encoding":"gzip, deflate", 
                        "Pragma":"no-cache",
                        "Content-type":"text/html; charset=UTF-8",
                        "Cache-Control":"no-cache",
                        "Connection":"Keep-Alive"}
        self.openapi= 'http://v.youku.com/player/getPlayList/VideoIDS/'

    def fcFLV(self, url):
        pattern = r'^http:\/\/www.youku.com/show_page/id_([\w=]+).html(?(\w)+=\d)*'
        if (re.match(pattern, url)==None):
            print u'你输入的地址不正确'
            return False
        else:
            req = urllib2.Request(url, headers=self.headers)
            content = urllib2.urlopen(req).read()
            pattern = '<a\s+href=[\'\"](?P<download_url>\S+)[\'\"]\s+title=(.*)charset=(.*)target=(.*)[\'\"]>(.*)<\/a>'
            links = re.compile(r''+pattern+'', re.IGNORECASE).finditer(content)
            download_url=[]
            threads=[]
            if links != None:
                for url in links:
                    download_url.append(url.group('download_url'))
                    print url.group('download_url')
                for durl in download_url:
                    threads.append(threading.Thread(target=self.parse, args=(durl,)))
                for i, t in enumerate(threads):
                    t.start()
                    time.sleep(2)                              
                for t in threads:
                    t.join()                
            else:
                print("URL Not Found")
                return False
            return True
 
    def parse(self, url):
        videoIDS=self.find_video_id_from_url(url)
        if videoIDS == False:
            print u'你输入的地址不正确'
            return False

        self.url = self.openapi + videoIDS
        req = urllib2.Request(url=self.url, headers=self.headers)
        res = urllib2.urlopen(req)
        content = res.read()
        videoData = json.loads(content)
        if (videoData['data'][0].has_key('error')):
            show_error=videoData['data'][0]['error']
            raise Exception(u'该视频仅对好友公开,或该视频已被删除！Invalid youku error: '+show_error)
        #检测支持格式，默认是mp4, 不支持mp4就用flv
        if "flv" in videoData['data'][0]['streamfileids']:
            fileid = videoData['data'][0]['streamfileids']['flv']        
        if "mp4" in videoData['data'][0]['streamfileids']:
            fileid = videoData['data'][0]['streamfileids']['mp4']
        if "flv" in videoData['data'][0]['segs']:
            media_blocks = videoData['data'][0]['segs']['flv']
            media_flag="flv"            
        if "mp4" in videoData['data'][0]['segs']:
            media_blocks = videoData['data'][0]['segs']['mp4']
            media_flag="mp4"

        title = videoData['data'][0]['title']
        ct = videoData['data'][0]['ct']
        cs = videoData['data'][0]['cs']
        img_src = videoData['data'][0]['logo']
        key1 = videoData['data'][0]['key1']
        key2 = videoData['data'][0]['key2']
        seed = videoData['data'][0]['seed']
        userid = videoData['data'][0]['userid']
        videoid = videoData['data'][0]['videoid']
        #时间总长
        totalsec = videoData['data'][0]['seconds']
        #showid_v2 = videoData['data'][0]['show']['showid']
        #paid = videoData['data'][0]['show']['paid']
        #copyright = videoData['data'][0]['show']['copyright']
        #theaterid = videoData['data'][0]['show']['theaterid']
        #以上内容是获得播放列表中的四个关键值，key1,key2,fileid,seed;
        sid = self.getSid()
        fid = self.getFileId(fileid, seed)
        blocks_key = self.getKey(media_blocks)

        #生成分段视频链接
        youku_file_url = "http://f.youku.com/player/getFlvPath/sid/"
        total_blocks = len(media_blocks)
        i = 0;
        urls = []
        while i<total_blocks :
            if i<= 15:
                block = '0'+ ("%x" % i )
            else:
                block = ("%x" % i)
            hex_current_block = block.upper()
            new_s1 = fid[0:8] + re.sub('^\d{2}', hex_current_block, fid[8:len(fid)])
            #result = re.sub(pattern, replacement, subject)
            url = youku_file_url + sid + '_' + hex_current_block + "/st/"+media_flag+"/fileid/" + new_s1 + "?K=" + blocks_key[i]
            urls.append((url, int(media_blocks[i]['size'])))
            i+=1

        urls, sizes = zip(*urls)
        total_size = sum(sizes)
        for val in urls:
            print val
        download_urls(urls, title, media_flag, total_size, '.')
        return True

        
    def getSid(self):
         sid = str(int(time.time()))+str(random.randint(0,9000)+10000)
         return sid

    def getFileId(self, fileid, seed):
        mixed = self.getMixString(seed)
        ids = fileid.split('*')
        del ids[len(ids)-1]
        readId = ''
        i=0
        while i<len(ids):
            idx = int(ids[i])
            readId+= mixed[idx:(idx+1)] 
            i+=1
        return readId

    @staticmethod 
    def getMixString(seed):
        source = list('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/\\:._-1234567890')
        mixed =''
        while source:
            seed = (int(seed) * 211 + 30031) % 65536
            index =  int( (seed / 65536) * len(source) )
            c = source.pop(index)
            mixed += str(c)
        return mixed

    @staticmethod 
    def getKey(k):
        arr = []
        for val in k:
            arr.append(val['k'])
        return arr

    @staticmethod
    def find_video_id_from_url(url):
        rs = re.match(r'^http://v.youku.com/v_show/id_([\w=]+).html', url)
        if rs == None:
            return False
        else:
            return rs.group(1)
                    
 
if __name__ == "__main__":
    fcflv = FCFLV()
    #fcflv.parse('http://v.youku.com/v_show/id_XNjA1MTg0NDE2.html?firsttime=2292')
    fcflv.parse(sys.argv[1])

